import { addTools, showPorts } from './utils';
import { setContext, showContext } from './vueService';
import debounce from 'lodash/debounce';
import eventBus from 'vue3-eventbus';
import { ElMessageBox } from 'element-plus/es';

let isNodeEdit = false;
const nodeLister = graph => {
  graph.on('node:added', ({ node, index, options }) => {
    const isClone = Reflect.has(options, 'position');
    if (!isClone) {
      const { x, y } = node.position();
      node.scale(1.1, 1.1);
      node.position(x, y);
    }
    const type = node.getProp('shape');
    if (type === 'rect' && node.attrs.text.zIndex !== 1) {
      node.setZIndex(-1);
    }
    //表示场景管理里面的组件
    const pathFlag = DATA_INFO.currentRoute.name === 'ScenesManage';
    if (pathFlag) {
      let flag = node.attrs.image.options.category;
      if (flag) {
        node.attr('.rank/fill', flag === 4 ? '#67C23A' : '#909399');
        node.attr('text/textWrap/ellipsis', false);
        node.attr('text/textWrap/', {});
      }

      eventBus.emit('addScreenNode', { type: 'node', value: node });
    }
    if (!pathFlag) {
      addTools(node, [{ name: 'node-editor' }], true);
    }

    // 修改拖入节点颜色、位置
    node.attr('.name/fill', '#666');
    node.attr('text/fill', '#666');
    node.attr('.image/refX', '50%');
    node.attr('.name/refX', '50%');
    node.attr('.image/refY', '50%');
    node.attr('.name/refY', '90%');
  });
  graph.on('node:moved', ({ e, node }) => {
    var cellJson = null;
    try {
      cellJson = node.toJSON();
      eventBus.emit('changePutGraph', {
        type: 'node',
        value: node,
        jsonValue: cellJson,
        operationType: 'update',
      });
    } catch {}
  });
  graph.on('node:resized', ({ e, node }) => {
    var cellJson = null;
    try {
      cellJson = node.toJSON();
      eventBus.emit('changePutGraph', {
        type: 'node',
        value: node,
        jsonValue: cellJson,
        operationType: 'update',
      });
    } catch {}
  });
  graph.on('node:rotated', ({ e, x, y, node, view }) => {
    var cellJson = null;
    try {
      cellJson = node.toJSON();
      eventBus.emit('changePutGraph', {
        type: 'node',
        value: node,
        jsonValue: cellJson,
        operationType: 'update',
      });
    } catch {}
  });
  graph.on('node:mouseenter', ({ e, node }) => {
    const pathFlag = DATA_INFO.currentRoute.name === 'ScenesManage';
    // 场景管理中内置组件不显示连接装
    if (pathFlag) {
      if (node.shape !== 'org-node') {
        return;
      }
    }

    showPorts(node, true);
  });
  graph.on('node:mouseleave', ({ e, node }) => {
    showPorts(node, false);
  });
  graph.on('node:click', ({ node }) => {
    showPorts(node, false);
  });
  graph.on('node:dblclick', ({ node, e }) => {
    if (
      node.attrs.image &&
      node.attrs.image.options &&
      (node.attrs.image.options.category === 1 ||
        node.attrs.image.options.category === 2)
    ) {
      isNodeEdit = false;
      eventBus.emit('changeVirtual', {
        name: node.attrs.text.text,
        flag: true,
        id: node.id,
        category: node.attrs.image.options.category,
      });
    } else {
      addTools(node, [{ name: 'node-editor' }], true);
      isNodeEdit = true;
    }
  });
  graph.on('node:change:attrs', ({ node, current, previous, options }) => {
    const pathFlag = DATA_INFO.currentRoute.name === 'ScenesManage';
    if (!pathFlag) {
      var cellJson = null;
      try {
        cellJson = node.toJSON();
        eventBus.emit('changePutGraph', {
          type: 'node',
          value: node,
          jsonValue: cellJson,
          operationType: 'update',
        });
      } catch {}
    }
  });
  graph.on('node:contextmenu', ({ e, x, y, cell, view }) => {
    if (cell) {
      cell.attr('text/fill', '#333');
    }
  });
};
const edgeLister = graph => {
  const options_ = [
    {
      name: 'source-arrowhead',
      args: {
        attrs: {},
      },
    },
    {
      name: 'target-arrowhead',
      args: {
        attrs: {
          fill: 'red',
        },
      },
    },
  ];
  graph.on('edge:connected', ({ isNew, currentCell, edge }) => {
    //表示场景管理里面的组件
    const pathFlag = DATA_INFO.currentRoute.name === 'ScenesManage';
    if (pathFlag) {
      let func = 'changePutGraph';
      if (isNew) {
        func = 'addScreenNode';
        edge.setConnector('normal');
        edge.setRouter('manhattan');
      }
      eventBus.emit(func, {
        type: 'edge',
        value: edge,
      });
    } else {
      var cellJson = null;
      try {
        cellJson = edge.toJSON();
        eventBus.emit('changePutGraph', {
          type: 'edges',
          jsonValue: cellJson,
          operationType: 'add',
        });
      } catch {}
    }
  });
  graph.on('edge:*', (isNew, currentCell) => {});
  graph.on('edge:mouseenter', ({ cell }) => {
    addTools(cell, options_, true);
  });
  graph.on('edge:mouseup', () => {
    const nodes = graph.getNodes();
    if (nodes.length) {
      for (let i = 0; i < nodes.length; i++) {
        showPorts(nodes[i], false);
      }
    }
  });

  graph.on('edge:mouseleave', ({ cell, view }) => {
    addTools(cell, options_, false);
    eventBus.emit('mouseLeaveEdge', { type: 'mouseLeaveEdge', value: view });
  });
  graph.on('edge:mousedown', ({ e, x, y, edge, view }) => {
    eventBus.emit('mouseDownEdge', {
      type: 'mouseDownEdge',
      value: edge,
      view: view,
    });
  });
};

// 创建防抖函数
const debouncedEdgeChangeVertices = debounce(({ edge }) => {
  // 处理连线路径点变化的逻辑
  eventBus.emit('changePutGraph', {
    type: 'edge',
    value: edge,
    jsonValue: edge.toJSON(),
    operationType: 'update',
  });
}, 300); // 设置防抖时间为 300 毫秒

let curCell = null;
const cellLister = graph => {
  graph.on('cell:contextmenu', ({ e, x, y, cell, view }) => {
    if (curCell) {
      curCell.attr('text/fill', '#333');
    }

    // 新的节点边框样式设置为红色
    curCell = cell;
    cell.attr('text/fill', '#0073F3');

    //当前节点
    showContextMenu(view, true, { graph, cell }, { e, x, y });
    // 显示节点配置信息
  });
  graph.on('cell:click', ({ e, x, y, cell, view }) => {
    // 新的节点边框样式重置
    if (curCell) {
      curCell.attr('text/fill', '#333');
    }

    showContext(false);
    eventBus.emit('hideDetail');
  });
  graph.on('cell:added', ({ cell, index, options }) => {
    if (!options.propertyPath?.includes('ports')) {
      const cellJson = cell.toJSON();
      const cell_ = cell.isNode();
      const pathFlag = DATA_INFO.currentRoute.name === 'ScenesManage';
      if (!pathFlag) {
        eventBus.emit('addScreenNode', {
          type: cell_ ? 'nodes' : 'edges',
          value: cellJson,
          operationType: 'add',
        });
      }
    }
  });
  graph.on('cell:removed', ({ cell, options }) => {
    if (!options.propertyPath?.includes('ports')) {
      const cellJson = cell.toJSON();
      const cell_ = cell.isNode();
      let type = cell_ ? 'nodes' : 'edges';
      let para = options;
      //不触发删除函数，执行默认删除
      const pathFlag = DATA_INFO.currentRoute.name === 'ScenesManage';
      if (
        !para.slient &&
        pathFlag &&
        (type !== 'edges' || cell.target.cell)
      ) {
        eventBus.emit('removeScreenNode', { type: type, value: cell });
      }
      if (!pathFlag) {
        eventBus.emit('removeScreenNode', {
          type: type,
          value: cellJson,
          operationType: 'delete',
        });
      }
    }
  });
  graph.on('cell:changed', ({ cell, options }) => {
    if (options.change && options.change == 'no') {
      return;
    }
  });
};
const blankLister = graph => {
  graph.on('scale', e => {
    eventBus.emit('changeGraphScale', { scale: e.sx });
  });
  graph.on('blank:contextmenu', ({ e, x, y, cell, view }) => {
    eventBus.emit('graphContext', { e: e, x: x, y: y });
  });
  graph.on('cell:click', ({ e, x, y, cell, view }) => {
    showContext(false);
    eventBus.emit('hideDetail');
  });
  graph.on('blank:click', () => {
    // 新的节点边框样式重置
    if (curCell) {
      curCell.attr('text/fill', '#333');
    }

    eventBus.emit('hideDetail');
    showContext(false);
  });
};

const bindKey = graph => {
  // 监听粘贴操作
  graph.bindKey(['ctrl+v', 'command+v'], () => {
    if (!graph.isClipboardEmpty() && !isNodeEdit) {
      graph.paste({ offset: 32 });
      graph.cleanSelection();
    }
  });
  // 监听复制操作
  graph.bindKey(['ctrl+c', 'command+c'], () => {
    if (!graph.isClipboardEmpty()) {
      graph.cleanClipboard();
    }
    const cells = graph.getSelectedCells();
    graph.copy(cells);
  });

  // 监听删除操作
  const listenerDel = () => {
    const isEmpty = graph.isSelectionEmpty();
    if (!isEmpty) {
      //需要判断path
      const pathFlag = DATA_INFO.currentRoute.name === 'ScenesManage';
      let cells = graph.getSelectedCells();
      if (!pathFlag) {
        graph.removeCells(cells);
      } else {
        let flag = false;
        for (let i = 0; i < cells.length; i++) {
          if (
            cells[i].attrs['.rank']?.fill === '#67C23A' ||
            cells[i].attrs['.rank']?.fill === '#F56C6C'
          ) {
            flag = true;
            break;
          }
        }

        if (flag) {
          ElMessageBox.confirm(`确认是否删除!`, {
            confirmButtonText: '删 除',
            cancelButtonText: '取 消',
            type: 'warning',
            center: true,
            customClass: 'delMessageBox',
            confirmButtonClass: 'delButtonClass',
          }).then(async () => {
            cells.forEach(item => {
              const type = item.isNode() ? 'nodes' : 'edges';
              eventBus.emit('removeScreenNode', { type: type, value: item });
            });
          });
        } else {
          cells.forEach(item => {
            const type = item.isNode() ? 'nodes' : 'edges';
            eventBus.emit('removeScreenNode', { type: type, value: item });
          });
        }
      }
    }
  };

  // 监听删除操作
  graph.bindKey(['delete', 'backspace'], e => {
    listenerDel();
  });

  // 监听全选操作
  graph.bindKey(['meta+a', 'ctrl+a', 'command+a'], (e) => {
    e.stopPropagation();
    e.preventDefault();
    const node = graph.getNodes();
    const edge = graph.getEdges();
    graph.resetSelection(node);
    graph.select(edge);
  });
  // // 监听撤销操作
  // graph.bindKey(['meta+z', 'ctrl+z', 'command+z'], () => {
  //   const flg = graph.canUndo();
  //   if (flg) {
  //     graph.undo();
  //   }
  // });
  // 向上箭头移动5个像素
  graph.bindKey(['up'], () => {
    eventBus.emit('elementMove', { x: 0, y: -5 });
  });
  // 向下箭头移动5个像素
  graph.bindKey(['down'], () => {
    eventBus.emit('elementMove', { x: 0, y: 5 });
  });
  // 向左箭头移动5个像素
  graph.bindKey(['left'], () => {
    eventBus.emit('elementMove', { x: -5, y: 0 });
  });
  // 向右箭头移动5个像素
  graph.bindKey(['right'], () => {
    eventBus.emit('elementMove', { x: 5, y: 0 });
  });

  // ctrl+向上箭头移动1个像素
  graph.bindKey(['meta+up', 'shift+up', 'command+up'], () => {
    eventBus.emit('elementMove', { x: 0, y: -1 });
  });
  // ctrl+向下箭头移动1个像素
  graph.bindKey(['meta+down', 'shift+down', 'command+down'], () => {
    eventBus.emit('elementMove', { x: 0, y: 1 });
  });
  // ctrl+向左箭头移动1个像素
  graph.bindKey(['meta+left', 'shift+left', 'command+left'], () => {
    eventBus.emit('elementMove', { x: -1, y: 0 });
  });
  // ctrl+向右箭头移动1个像素
  graph.bindKey(['meta+right', 'shift+right', 'command+right'], () => {
    eventBus.emit('elementMove', { x: 1, y: 0 });
  });
};

function showContextMenu(view, show, nodeAndGraph, options) {
  const { x, y } = options;
  const { cell } = nodeAndGraph;
  // 获取节点的 bounding box
  const box = cell.getBBox();
  // 计算鼠标点击位置到节点左下角的距离 相对点
  const pointX = box.x;
  const pointY = box.y + box.height;
  options.x = x - pointX;
  options.y = y - pointY;

  let type = '';
  if (cell.isNode()) {
    type = 'node';
  }
  if (cell.isEdge()) {
    type = 'edge';
  }
  setContext(type, view, nodeAndGraph, options);
  showContext(show);
}

export const graphLister = graph => {
  cellLister(graph);
  nodeLister(graph);
  edgeLister(graph);
  blankLister(graph);
  bindKey(graph);
};

export const engineGraphLister = graph => {
  graphLister(graph);
  graph.on('edge:change:vertices', ({ edge }) => {
    debouncedEdgeChangeVertices({ edge });
  });

  graph.on('blank:mousedown', () => {
    eventBus.emit('mouseDownBlank');
  });
  graph.on('cell:selected', ({ cell }) => {
    eventBus.emit('cellSelected', { cell: cell });
  });
  graph.on('cell:unselected', ({ cell }) => {
    eventBus.emit('cellUnSelected', { cell: cell });
  });
  let cx = 0;
  let cy = 0;
  graph.on('edge:move', ({ x, y }) => {
    cx = x;
    cy = y;
  });
  // 重写选中线后偏移方法，X6选中线后移动存在bug
  graph.on('edge:moving', ({ x, y, edge }) => {
    const selectedCells = graph.getSelectedCells();
    Object.values(selectedCells).forEach(cell => {
      if (cell.id === edge.id) {
        eventBus.emit('elementMove', { x: x - cx, y: y - cy, edgeID: edge.id });
        cx = x;
        cy = y;
      }
    });
  });
  graph.on('edge:mouseup', ({ edge }) => {
    eventBus.emit('changePutGraph', {
      type: 'edge',
      value: edge,
      jsonValue: edge.toJSON(),
      operationType: 'update',
    });
    const nodes = graph.getNodes();
    if (nodes.length) {
      for (let i = 0; i < nodes.length; i++) {
        showPorts(nodes[i], false);
      }
    }
  });
};

export const copyGraphLister = graph => {
  graph.on('blank:click', () => {
    eventBus.emit('hideDetail');
    showContext(false);
  });

  graph.on('node:dblclick', ({ node, e }) => {
    if (
      node.attrs.image &&
      node.attrs.image.options &&
      (node.attrs.image.options.category === 1 ||
        node.attrs.image.options.category === 2)
    ) {
      eventBus.emit('changeVirtual', {
        name: node.attrs.text.text,
        flag: true,
        id: node.id,
        category: node.attrs.image.options.category,
      });
    } else {
      addTools(node, [{ name: 'node-editor' }], true);
    }
  });

  graph.on('cell:contextmenu', ({ e, x, y, cell, view }) => {
    //当前节点, 副本组件内置组件和集群网络不展示内容
    if (
      cell.attrs.image.options.category !== 4 &&
      cell.attrs.image.options.category !== 5
    ) {
      // 显示节点配置信息
      showContextMenu(view, true, { graph, cell }, { e, x, y });
    }
  });
};
